﻿namespace Blaze.Framework.LuaExtensions
{
    using System;
    using System.Collections.Generic;
    using UnityEngine;
    using XLua;

    /// <summary>
    /// 提供向lua注入组件数据和引用的机制。
    /// </summary>
    public class LuaInjection : MonoBehaviour
    {
        /// <summary>
        /// 所有在编辑器中定义的字段。
        /// </summary>
        [HideInInspector]
        public List<LuaFieldPair> Fields = new List<LuaFieldPair>();

        /// <summary>
        /// 向指定的lua表注入。
        /// </summary>
        /// <param name="table">需要注入的表</param>
        public void Inject(LuaTable table)
        {
            if (table == null)
                throw new ArgumentNullException(nameof(table));

            foreach (var pair in Fields)
            {
                switch (pair.T)
                {
                    case LuaFieldType.GameObject:
                        table.Set(pair.K, pair.V);
                        break;
                    case LuaFieldType.String:
                        table.Set(pair.K, pair.V1);
                        break;
                    case LuaFieldType.Number:
                        table.Set(pair.K, pair.V2);
                        break;
                    case LuaFieldType.Boolean:
                        table.Set(pair.K, pair.V2 != 0);
                        break;
                    case LuaFieldType.LuaTable:
                        var behaviour = (LuaBehaviour) pair.V;
                        behaviour.Initialize();
                        table.Set(pair.K, behaviour.LuaTable);
                        break;
                    case LuaFieldType.Component:
                    case LuaFieldType.Asset:
                        table.Set(pair.K, pair.V);
                        break;
                }
            }
        }

        /// <summary>
        /// <para>
        /// Implement this method to receive a callback after Unity de-serializes your object.
        /// </para>
        /// </summary>
        public void OnAfterDeserialize()
        {
            mFields.Clear();
            for (var i = 0; i < Fields.Count; i++)
                mFields.Add(Fields[i].K, Fields[i]);
        }

        /// <summary>
        /// <para>
        /// Implement this method to receive a callback before Unity serializes your object.
        /// </para>
        /// </summary>
        public void OnBeforeSerialize()
        {
        }

        private readonly Dictionary<string, LuaFieldPair> mFields = new Dictionary<string, LuaFieldPair>();
    }
}